﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Data;
using Microsoft.Win32;
using System.IO;
using System.Configuration;
using System.Net;
using System.ComponentModel;
using System.Collections;
using System.Text.RegularExpressions;

namespace TaxonomyReader
{
    public enum FileStatus
    {
        [DescriptionAttribute("Reading")]
        reading,
        [DescriptionAttribute("Downloading")]
        downloading,
        [DescriptionAttribute("DownloadComplete")]
        downloadcompleted,
        [DescriptionAttribute("Completed")]
        completed
    }
    public class ProxySettings
    {
        public string server { get; set; }
        public int port { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string Domain { get; set; }
    }

    public class TaxonomyLoader
    {
        internal static string DownloadFilesPath { get; set; }
        internal static string SerializedFilesPath { get; set; }

        public delegate void ProgressChangeDelegate(string file, FileStatus status, int percentComplete);
        
        public ProgressChangeDelegate progressChanged;

        DataTable m_dtLoc;
        SerializeDeserialize m_srDr = new SerializeDeserialize();

        DataTable m_dtDefArc;
        DataTable m_dtCalArc;
        DataTable m_dtPresArc;

        ProxySettings m_proxyObj;

        public TaxonomyLoader(string DownloadFilesPath, string SerializedFilesPath, ProxySettings proxObj)
        {
            TaxonomyLoader.DownloadFilesPath = DownloadFilesPath;
            TaxonomyLoader.SerializedFilesPath = SerializedFilesPath;

            m_proxyObj = proxObj;
        }

        /// <summary>
        /// this will load current taxonomy's schema, linkbases + the imported taxonomies
        /// </summary>
        /// <param name="entryXSdPath">the entrypoint path of a taxonomy</param>
        /// <param name="referredImport">true if want to load imported taxonomies entirely, false to load only schema,label-linkbase of imported taxonomies</param>
        /// <returns></returns>
        public XsdBO LoadEntireTaxonomy(string entryXSdPath, bool loadImportComplete)
        {
            string[] spl1 = entryXSdPath.Split('\\');
            string entryXsdFileName = spl1[spl1.Length-1];

            string entryXsdFolder = entryXSdPath.Substring(0, entryXSdPath.Length - entryXsdFileName.Length);

            //loading first taxonomy
            m_mainXsd = LoadTaxonomy(entryXSdPath,true);
            
            if (m_mainXsd.Imports != null)
            {
                HandleImports(m_mainXsd, loadImportComplete);
            }

            return m_mainXsd;
        }

        XsdBO m_mainXsd;

        private bool CheckTaxonomyLoaded(string xsdName, XsdBO xsd)
        {
            if (xsd.XsdName == xsdName)
            {
                return true;
            }
            else if (xsd.ImportedXsds != null)
            {
                foreach (XsdBO xsd1 in xsd.ImportedXsds)
                {
                    bool m = CheckTaxonomyLoaded(xsdName, xsd1);
                    if (m)
                        return m;
                }
            }

            return false;
        }

        /// <summary>
        /// recursive function to load imported xsds in the passed XsdBO object
        /// </summary>
        /// <param name="xsd"></param>
        /// <param name="xsdFolder">physical path of xsd</param>
        //public void HandleImports(XsdBO xsd, string xsdFolder, bool loadImportComplete)
        public void HandleImports(XsdBO xsd, bool loadImportComplete)
        {
            foreach (ImportBO import in xsd.Imports)
            {
                //ignore instance, linkbase and xbrldt files
                if (import.Namespace.ToLower() == "http://www.xbrl.org/2003/linkbase" ||
                    import.Namespace.ToLower() == "http://www.xbrl.org/2003/instance" ||
                    import.Namespace.ToLower() == "http://xbrl.org/2005/xbrldt" ||
                    import.Namespace.ToLower() == "http://www.xbrl.org/2003/xlink" ||
                    import.Namespace.ToLower() == "http://www.w3.org/1999/xlink" ||
                    import.Namespace.ToLower() == "http://www.xbrl.org/2006/ref" //||
                    //import.Namespace.ToLower().Contains("http://www.xbrl.org/dtr") ||
                    //import.Namespace.ToLower().Contains("http://xbrl.us/us-gaap/negated/2008-03-31")
                    )
                    //||
                    //import.Namespace.ToLower().Contains("http://www.xbrl.org/") ||
                    //import.Namespace.ToLower().Contains("http://xbrl.org/") ||
                    //import.Namespace.ToLower().Contains("http://www.w3.org/"))
                    continue;

                //check if this taxonomy is already loaded before from root xsd onwards
                string schemaLocation = import.SchemaLocation.Replace('\\', '/');
                string[] spl = schemaLocation.Split('/');
                string xsdName = spl[spl.Length - 1];
                if (CheckTaxonomyLoaded(xsdName,m_mainXsd))
                    continue;

                //string xsdPath = getPathForFile(m_actualPath,import.SchemaLocation);

                //if (import.SchemaLocation.Contains("http://"))
                //{
                //    xsdPath = import.SchemaLocation;
                //}
                //else
                //{
                //    if (m_actualPath.StartsWith("http://"))
                //    {
                //        xsdPath = 

                //    xsdPath = xsdFolder + import.SchemaLocation;
                //}

                //load imported taxonomy
                XsdBO importedXsd = LoadTaxonomy(getPathForFile(import.ActualPath,import.SchemaLocation), loadImportComplete);

                ////calculate other paths as per imported schema folder
                //string[] spl1 = importedXsd.ActualSchemaPath.Split('\\');
                //string importedXsdFolder = importedXsd.ActualSchemaPath.Substring(0,
                //    importedXsd.ActualSchemaPath.Length - spl1[spl1.Length-1].Length);

                if (xsd.ImportedXsds == null)
                    xsd.ImportedXsds = new List<XsdBO>();

                if (importedXsd.HasError)
                    xsd.HasError = true;

                xsd.ImportedXsds.Add(importedXsd);

                HandleImports(importedXsd, loadImportComplete);
            }
        }

        /// <summary>
        /// this will load single taxonomy's schema elements and linkbases for xsdPath
        /// </summary>
        /// <param name="xsdPath"></param>
        /// <returns></returns>
        public XsdBO LoadTaxonomy(string actualPath, bool loadAllLinkBases)
        {
            XsdBO xsd = new XsdBO();

            try
            {
                string[] spl = actualPath.Split('\\');
                if (spl.Length == 1)
                    spl = actualPath.Split('/');
                if (actualPath.StartsWith("http"))
                {
                    spl = actualPath.Split('/');
                }
                string xsdFileName = spl[spl.Length - 1];
                object obj = null;

                if (progressChanged != null)
                    progressChanged(actualPath, FileStatus.reading, 0);

                //check if there is serialized file of the Schema.
                //if present load object from it, else create and serialize its
                
                obj = m_srDr.Deserialize(xsdFileName);
                if (obj == null)
                {
                    //xsdpath
                    string xsdPath = GetActualPath(actualPath);

                    //serializing only the schema, not linkbase, imported schema objects
                    xsd = ReadTaxonomySchema(xsdPath, actualPath);
                    xsd.ActualSchemaPath = xsdPath;
                    xsd.XsdName = xsdFileName;
                    m_srDr.Serialize(xsdFileName, xsd);
                }
                else
                {
                    xsd = (XsdBO)obj;
                    xsd.ActualSchemaPath = GetActualPath(actualPath);
                }

                #region get file paths
                List<string> presLinPath = new List<string>();
                List<string> calcLinPath = new List<string>();
                List<string> defLinPath = new List<string>();
                List<string> labLinPath = new List<string>();
                //not reading
                List<string> refLinPath = new List<string>();
                //string xsdFolder = xsdPath.Substring(0, xsdPath.Length - xsdFileName.Length);
                foreach (LinkBaseRefBO linkRef in xsd.LinkbaseRefs)
                {
                    string path1 = getPathForFile(actualPath, linkRef.Href);
                    if (linkRef.LinkBaseType == LinkBaseType.calculationLink)
                    {
                        calcLinPath.Add(GetActualPath(path1));
                    }
                    else if (linkRef.LinkBaseType == LinkBaseType.definitionLink)
                    {
                        defLinPath.Add(GetActualPath(path1));
                    }
                    else if (linkRef.LinkBaseType == LinkBaseType.labelLink)
                    {
                        labLinPath.Add(GetActualPath(path1));
                    }
                    else if (linkRef.LinkBaseType == LinkBaseType.presentationLink)
                    {
                        presLinPath.Add(GetActualPath(path1));
                    }
                    else if (linkRef.LinkBaseType == LinkBaseType.referenceLink)
                    {
                        refLinPath.Add(GetActualPath(path1));
                    }
                }
                #endregion

                #region Load Linkbases
                xsd.PresLink = new List<PresentationLinkbaseBO>();
                xsd.DefLink = new List<DefinitonLinkbaseBO>();
                xsd.LabLink = new List<LabelLinkbaseBO>();
                xsd.CalcLink = new List<CalculationLinkbaseBO>();

                //check if there is serialized file of the linkbase.
                //if present load object from it, else create and serialize its
                string filename = "";
                string[] spl1 = null;

                if (loadAllLinkBases)
                {
                    //presentation linkbase paths
                    if (presLinPath.Count > 0)
                    {
                        foreach (string presPath in presLinPath)
                        {
                            if (presPath == null || presPath == "")
                                continue;

                            spl1 = presPath.Split('\\');
                            filename = spl1[spl1.Length - 1];

                            if (progressChanged != null)
                                progressChanged(filename, FileStatus.reading, 20);

                            obj = m_srDr.Deserialize(filename);
                            if (obj == null)
                            {
                                PresentationLinkbaseBO prlbo = ReadPresentationLinkbase(presPath);
                                prlbo.LinkBaseName = filename;
                                xsd.PresLink.Add(prlbo);
                                m_srDr.Serialize(filename, prlbo);
                            }
                            else
                            {
                                xsd.PresLink.Add((PresentationLinkbaseBO)obj);
                            }
                        }
                    }
                    //calculation linkbase paths
                    if (calcLinPath.Count > 0)
                    {
                        foreach (string calPath in calcLinPath)
                        {
                            if (calPath == null || calPath == "")
                                continue;

                            spl1 = calPath.Split('\\');
                            filename = spl1[spl1.Length - 1];

                            if (progressChanged != null)
                                progressChanged(filename, FileStatus.reading, 40);

                            obj = m_srDr.Deserialize(filename);
                            if (obj == null)
                            {
                                CalculationLinkbaseBO callbo = ReadCalculationLinkbase(calPath);
                                callbo.LinkBaseName = filename;
                                xsd.CalcLink.Add(callbo);
                                m_srDr.Serialize(filename, callbo);
                            }
                            else
                            {
                                xsd.CalcLink.Add((CalculationLinkbaseBO)obj);
                            }
                        }
                    }
                    //definition linkbase paths
                    if (defLinPath.Count > 0)
                    {
                        foreach (string defPath in defLinPath)
                        {
                            if (defPath == null || defPath == "")
                                continue;

                            spl1 = defPath.Split('\\');
                            filename = spl1[spl1.Length - 1];

                            if (progressChanged != null)
                                progressChanged(filename, FileStatus.reading, 60);

                            obj = m_srDr.Deserialize(filename);
                            if (obj == null)
                            {
                                DefinitonLinkbaseBO deflbo = ReadDefinitionLinkbase(defPath);
                                deflbo.LinkBaseName = filename;
                                xsd.DefLink.Add(deflbo);
                                m_srDr.Serialize(filename, deflbo);
                            }
                            else
                            {
                                xsd.DefLink.Add((DefinitonLinkbaseBO)obj);
                            }
                        }
                    }
                }

                //label linkbase paths
                if (labLinPath.Count > 0)
                {
                    foreach (string labPath in labLinPath)
                    {
                        if (labPath == null || labPath == "")
                            continue;

                        spl1 = labPath.Split('\\');
                        filename = spl1[spl1.Length - 1];

                        if (progressChanged != null)
                            progressChanged(filename, FileStatus.reading, 80);

                        obj = m_srDr.Deserialize(filename);
                        if (obj == null)
                        {
                            LabelLinkbaseBO lablbo = ReadLabelLinkbase(labPath);
                            lablbo.LinkBaseName = filename;
                            xsd.LabLink.Add(lablbo);
                            m_srDr.Serialize(filename, lablbo);
                        }
                        else
                        {
                            xsd.LabLink.Add((LabelLinkbaseBO)obj);
                        }
                    }
                }
                
                

                #endregion
            }
            catch (FileNotFoundException fex)
            {
                if (fex.Message == "FileDownloadFailed")
                {
                    xsd.HasError = true;
                    xsd.XsdErrors = new XsdError();
                    xsd.XsdErrors.fileDownloadFailed = fex.FileName;
                }
                else if (fex.Message == "FileNotFound")
                {
                    xsd.HasError = true;
                    xsd.XsdErrors = new XsdError();
                    xsd.XsdErrors.fileNotFound = fex.FileName;
                }
            }
            catch (Exception ex)
            {
                xsd.HasError = true;
                xsd.XsdErrors = new XsdError();
                xsd.XsdErrors.fileInvalid = ex.Message;
            }

            //if (progressChanged != null)
            //    progressChanged(xsdPath, FileStatus.completed,100);

            return xsd;
        }

        private string GetActualPath(string xsdPath)
        {
            if (xsdPath.StartsWith("http"))
            {
                string downloadFolder = TaxonomyLoader.DownloadFilesPath;

                if (!Directory.Exists(downloadFolder))
                {
                    Directory.CreateDirectory(downloadFolder);
                }

                string[] spl1 = xsdPath.Split('/');
                string xsdFileName = spl1[spl1.Length - 1];
                //always download the file ??

                if (!File.Exists(downloadFolder + xsdFileName))
                {
                    //File.Create(downloadFolder + xsdFileName,);

                    try
                    {
                        //download the file
                        WebClient wc1 = new WebClient();
                        //handle proxy settings
                        if (m_proxyObj != null)
                        {
                            //wc1.Proxy = WebProxy.GetDefaultProxy();
                            WebProxy wb = new WebProxy(m_proxyObj.server + ":" + m_proxyObj.port, true);
                            wb.Credentials = new NetworkCredential(m_proxyObj.Username, m_proxyObj.Password, m_proxyObj.Domain);
                            wc1.Proxy = wb;
                        }
                        //..
                        if (progressChanged != null)
                            progressChanged(xsdPath, FileStatus.downloading, 0);

                        wc1.DownloadFile(xsdPath, downloadFolder + xsdFileName);

                        if (progressChanged != null)
                            progressChanged(xsdPath, FileStatus.downloadcompleted, 100);

                        xsdPath = downloadFolder + xsdFileName;
                    }
                    catch
                    {
                        //File.Delete(downloadFolder + xsdFileName);
                        throw new FileNotFoundException("FileDownloadFailed", xsdPath);
                    }
                }
                else
                {
                    xsdPath = downloadFolder + xsdFileName;
                }
            }

            xsdPath = xsdPath.Replace('/', '\\');

            if (!File.Exists(xsdPath))
            {
                throw new FileNotFoundException("FileNotFound",xsdPath);
            }

            return xsdPath;
        }

        /// <summary>
        /// Resolves the path of the linkbases or imported taxonomies based on the path of the current taxonomy file
        /// </summary>
        /// <param name="taxonomyPath">Path of the current taxonomy file</param>
        /// <param name="relativePath">Path in the 'href' attribute of the linkbase Or Path in the 'schemaLocation' attribute of the imports</param>
        /// <returns>Resolved path of the refered linkbase or taxonomy file</returns>
        private string getPathForFile(string taxonomyPath, string relativePath)
        {
            if (relativePath.StartsWith("http"))
                return relativePath;

            if (taxonomyPath == null)
                return relativePath;

            Uri url;
            if (taxonomyPath.StartsWith("http"))
            {
                url = new Uri(new Uri(taxonomyPath), relativePath);
                return url.AbsoluteUri;
            }
            else
            {
                url = new Uri(new Uri(taxonomyPath), relativePath);
                return url.LocalPath;
            }
        }

        string m_actualPath = "";

        public XsdBO ReadTaxonomySchema(string schemaPath, string actualPath)
        {
            try
            {
                m_actualPath = schemaPath;

                XsdBO xsd = new XsdBO();

                XDocument xsdDoc = XDocument.Load(schemaPath);
                xsd.targetNamespace = xsdDoc.Root.Attribute("targetNamespace").Value;

                List<XElement> xeleLnBsRefs = (from xeleAn in xsdDoc.Root.Elements()
                                               where xeleAn.Name.LocalName == "annotation"
                                               from xeleApp in xeleAn.Elements()
                                               where xeleApp.Name.LocalName == "appinfo"
                                               from xele in xeleApp.Elements()
                                               where xele.Name.LocalName == "linkbaseRef"
                                               select xele).ToList<XElement>();

                List<LinkBaseRefBO> linkbases = new List<LinkBaseRefBO>();
                foreach (XElement xele in xeleLnBsRefs)
                {
                    LinkBaseRefBO temp = new LinkBaseRefBO();
                    temp.ArcRole = ArcRole.Linkbase;
                    temp.ActualPath = actualPath;
                    temp.Href = xele.Attributes().FirstOrDefault(a => a.Name.LocalName == "href").Value;
                    string role = xele.Attributes().FirstOrDefault(a => a.Name.LocalName == "role").Value;
                    temp.LinkBaseType = (LinkBaseType)EnumExtensions.GetEnumValue(role, typeof(LinkBaseType));
                    temp.LinkType = XLinkType.simple;
                    linkbases.Add(temp);
                }
                xsd.LinkbaseRefs = linkbases;

                List<XElement> xeleRlTyp = (from xeleAn in xsdDoc.Root.Elements()
                                            where xeleAn.Name.LocalName == "annotation"
                                            from xeleApp in xeleAn.Elements()
                                            where xeleApp.Name.LocalName == "appinfo"
                                            from xele in xeleApp.Elements()
                                            where xele.Name.LocalName == "roleType"
                                            select xele).ToList<XElement>();

                List<RoleTypeBO> roletypes = new List<RoleTypeBO>();
                foreach (XElement xele in xeleRlTyp)
                {
                    RoleTypeBO temp = new RoleTypeBO();
                    temp.RoleUri = xele.Attribute("roleURI").Value;
                    temp.Id = xele.Attribute("id").Value;
                    try
                    {
                        var q = from xele1 in xele.Elements()
                                where xele1.Name.LocalName == "definition"
                                select xele1;

                        XElement defEl = (from xele1 in xele.Elements()
                                          where xele1.Name.LocalName == "definition"
                                          select xele1).ToList<XElement>()[0];
                        if (defEl != null)
                            temp.Definition = defEl.Value;
                    }
                    catch
                    {
                        temp.Definition = "(No Definition)" + temp.RoleUri;
                    }

                    temp.LinkUsedOn = new List<LinkBaseType>();
                    try
                    {
                        List<XElement> linkEls = (from xele2 in xele.Elements()
                                                  where xele2.Name.LocalName == "usedOn"
                                                  select xele2).ToList<XElement>();
                        foreach (XElement xele2 in linkEls)
                        {
                            temp.LinkUsedOn.Add((LinkBaseType)Enum.Parse(typeof(LinkBaseType),
                            xele2.Value.Replace("link:", "")));
                        }
                    }
                    catch { }

                    roletypes.Add(temp);
                }
                xsd.RoleTypes = roletypes;

                List<XElement> xeleImp = (from xele in xsdDoc.Root.Elements()
                                          where xele.Name.LocalName == "import"
                                          select xele).ToList<XElement>();

                List<ImportBO> imports = new List<ImportBO>();
                foreach (XElement xele in xeleImp)
                {
                    ImportBO temp = new ImportBO();
                    temp.Namespace = xele.Attribute("namespace").Value;
                    temp.SchemaLocation =xele.Attribute("schemaLocation").Value;
                    temp.ActualPath = actualPath;
                    imports.Add(temp);
                }
                xsd.Imports = imports;

                foreach (XAttribute atr in xsdDoc.Root.Attributes())
                {
                    if (xsd.Namespaces == null)
                        xsd.Namespaces = new List<string>();

                    xsd.Namespaces.Add(atr.Name.LocalName + ":" + atr.Value);
                }

                List<XElement> complexTypes = (from xele in xsdDoc.Root.Elements()
                                               where xele.Name.LocalName == "complexType"
                                               select xele).ToList<XElement>();

                foreach (XElement xCm in complexTypes)
                {
                    ComplexType cmp = new ComplexType();
                    cmp.name = xCm.Attribute("name").Value;
                    List<XElement> xeleRestriction = (from xele in xCm.Elements()
                                                      where xele.Name.LocalName == "simpleContent"
                                                      from xele1 in xele.Elements()
                                                      where xele1.Name.LocalName == "restriction"
                                                      select xele1).ToList<XElement>();

                    if (xeleRestriction != null && xeleRestriction.Count > 0)
                    {
                        XElement xeleRes = xeleRestriction[0];
                        if (xeleRes.Attribute("base") != null)
                            cmp.baseType = xeleRes.Attribute("base").Value;

                        cmp.restriction = xeleRes.Value;
                    }

                    if (xsd.ComplexTypes == null)
                        xsd.ComplexTypes = new List<ComplexType>();

                    xsd.ComplexTypes.Add(cmp);
                }

                Hashtable hstXmlNs = new Hashtable();

                List<XElement> xeleElements = (from xele in xsdDoc.Root.Elements()
                                               where xele.Name.LocalName == "element"
                                               select xele).ToList<XElement>();

                List<ElementBO> elements = new List<ElementBO>();
                foreach (XElement xele in xeleElements)
                {

                    ElementBO temp = new ElementBO();
                    temp.Id = xele.Attribute("id").Value;
                    temp.Name = xele.Attribute("name").Value;
                    try
                    {
                        temp.PeriodType = (XsdPeriodType)Enum.Parse(typeof(XsdPeriodType),
                                            xele.Attributes().FirstOrDefault(a => a.Name.LocalName == "periodType").Value);
                    }
                    catch
                    {
                        //description of some other type . 
                        //may not required in this taxonomy load

                        continue;
                    }

                    try
                    {
                        temp.Type = (XsdType)Enum.Parse(typeof(XsdType), xele.Attribute("type").Value.Replace("xbrli:", ""));
                    }
                    catch
                    {
                        //description of some other type
                        temp.Type_str = xele.Attribute("type").Value;
                        string ns = temp.Type_str.Split(':')[0];
                        if (hstXmlNs[ns] == null)
                        {
                            hstXmlNs.Add(ns, xsdDoc.Root.Attributes().FirstOrDefault(a => a.Name.LocalName == ns).Value);
                        }
                        temp.Type_str = temp.Type_str + ":::" + hstXmlNs[ns];
                    }

                    try
                    {
                        temp.SubstitutionGroup = (XsdSubstitutionGroup)Enum.Parse(typeof(XsdSubstitutionGroup),
                                        xele.Attribute("substitutionGroup").Value.Replace("xbrli:", "").Replace("xbrldt:", ""));
                    }
                    catch
                    {
                        //description of some other type . may not required in this taxonomy load
                        continue;
                    }

                    try { temp.IsAbstract = xele.Attribute("abstract").Value == "false" ? false : true; }
                    catch { temp.IsAbstract = false; }  //what is default abstract

                    try
                    {
                        temp.Balance = xele.Attributes().FirstOrDefault(a => a.Name.LocalName == "balance")
                                    .Value == "debit" ? XsdBalance.debit : XsdBalance.credit;
                    }
                    catch { }

                    try { temp.Nillable = xele.Attribute("nillable").Value == "true" ? true : false; }
                    catch { }

                    elements.Add(temp);
                }
                xsd.Elements = elements;

                return xsd;

            }
            catch
            {
                return null;
            }
        }

        public LabelLinkbaseBO ReadLabelLinkbase(string labLinPath)
        {
            try
            {
                LabelLinkbaseBO labBO = new LabelLinkbaseBO();
                string[] spl = labLinPath.Split('\\');
                labBO.Href = spl[spl.Length - 1];

                labBO.Labels = new List<LabelBO>();
                DataSet dsLab = new DataSet();
                dsLab.ReadXml(labLinPath);

                m_dtLoc = dsLab.Tables["loc"];

                foreach (DataRowView drvLbArc in dsLab.Tables["labelArc"].DefaultView)
                {
                    LabelBO lab = new LabelBO();
                    lab.ArcRole = (ArcRole)EnumExtensions.GetEnumValue(drvLbArc["arcrole"].ToString(), typeof(ArcRole));
                    string labId = drvLbArc["to"].ToString();

                    try { lab.Use = (ArcUse)Enum.Parse(typeof(ArcUse), drvLbArc["use"].ToString()); }
                    catch { lab.Use = ArcUse.use; }

                    dsLab.Tables["loc"].DefaultView.RowFilter = "label='" + drvLbArc["from"].ToString() + "'";

                    lab.Href = GetHref(dsLab.Tables["loc"].DefaultView[0]["href"].ToString());
                    //original
                    //lab.Href = dsLab.Tables["loc"].DefaultView[0]["href"].ToString();

                    if (lab.Use == ArcUse.prohibit)
                    {
                        //this is label of a locator
                        //whose href will have restricted labelId

                        dsLab.Tables["loc"].DefaultView.RowFilter = "label='" + drvLbArc["to"].ToString();
                        if (dsLab.Tables["loc"].DefaultView.Count > 0)
                        {
                            try
                            {
                                //the href will be pointing to label-id of the prohibited label
                                lab.LabelId = dsLab.Tables["loc"].DefaultView[0]["href"].ToString();
                                //this is xsd#labelid
                            }
                            catch { /*bad labelArc*/ }
                        }
                        else
                        {
                            //no locator, direct label is given
                            lab.LabelId = drvLbArc["to"].ToString();
                        }

                        continue;
                    }

                    //if use='optional' this is label for a label tag
                    dsLab.Tables["label"].DefaultView.RowFilter = "label='" + drvLbArc["to"].ToString() + "'";
                    if (dsLab.Tables["label"].DefaultView[0]["role"].ToString() == "")
                    {
                        //ommited label role
                        lab.LabelRole = LabelRole.label.ToDescriptionString();
                    }
                    try { lab.LabelId = dsLab.Tables["label"].DefaultView[0]["id"].ToString(); }
                    catch { }

                    //lab.LabelRole = (LabelRole)EnumExtensions.GetEnumValue(dsLab.Tables["label"]
                    //    .DefaultView[0]["role"].ToString(), typeof(LabelRole));
                    lab.LabelRole = dsLab.Tables["label"].DefaultView[0]["role"].ToString();

                    lab.Label = dsLab.Tables["label"].DefaultView[0]["label_Text"].ToString();
                    lab.Language = dsLab.Tables["label"].DefaultView[0]["lang"].ToString();

                    labBO.Labels.Add(lab);
                }

                #region _c
                ////foreach (DataRowView drvLab in dsLab.Tables["label"].DefaultView)
                ////{
                ////    try
                ////    {
                ////        LabelBO lab = new LabelBO();

                ////        lab.Label = drvLab["label_Text"].ToString();
                ////        lab.Language = drvLab["lang"].ToString();

                ////        if (drvLab["role"].ToString() == "")
                ////        {
                ////            //ommited label role
                ////            lab.LabelRole = LabelRole.label;
                ////        }

                ////        lab.LabelRole = (LabelRole)EnumExtensions.GetEnumValue(drvLab["role"].ToString(), typeof(LabelRole));

                ////        dsLab.Tables["labelArc"].DefaultView.RowFilter = "to='" + drvLab["label"] + "'";

                ////        try
                ////        {
                ////            if (dsLab.Tables["labelArc"].DefaultView[0]["use"].ToString() == "prohibit")
                ////                lab.Use = (ArcUse)Enum.Parse(typeof(ArcUse), dsLab.Tables["labelArc"].DefaultView[0]["use"].ToString());
                ////        }
                ////        catch { lab.Use = ArcUse.use; }

                ////        lab.ArcRole = (ArcRole)EnumExtensions.GetEnumValue(dsLab.Tables["labelArc"]
                ////            .DefaultView[0]["arcrole"].ToString(), typeof(ArcRole));

                ////        m_dtLoc.DefaultView.RowFilter = "label='" + dsLab.Tables["labelArc"].DefaultView[0]["from"] + "'";
                ////        lab.Href = m_dtLoc.DefaultView[0]["href"].ToString();

                ////        labBO.Labels.Add(lab);
                ////    }
                ////    catch
                ////    {

                ////    }
                ////}
                #endregion

                return labBO;
            }
            catch
            {
                return null;
            }
            //handle concept-label, label-concept types
        }

        #region Definition

        public DefinitonLinkbaseBO ReadDefinitionLinkbase(string defLinPath)
        {
            DefinitonLinkbaseBO defBO = new DefinitonLinkbaseBO();
            string[] spl = defLinPath.Split('\\');
            defBO.Href = spl[spl.Length - 1];

            try
            {
                defBO.DefintionLinks = new List<DefinitionLinkBO>();

                DataSet dsDefLin = new DataSet();
                dsDefLin.ReadXml(defLinPath);

                m_dtDefArc = dsDefLin.Tables["definitionArc"];
                m_dtLoc = dsDefLin.Tables["loc"];

                foreach (DataRow dr in dsDefLin.Tables["DefinitionLink"].Rows)
                {
                    DefinitionLinkBO defExtLink = new DefinitionLinkBO();
                    defExtLink.ExtendedLinkRole = dr["role"].ToString();
                    dsDefLin.Tables["roleRef"].DefaultView.RowFilter = "roleURI='" + defExtLink.ExtendedLinkRole + "'";
                    defExtLink.Href = dsDefLin.Tables["roleRef"].DefaultView[0]["href"].ToString();
                    int defLink_Id = Convert.ToInt32(dr["DefinitionLink_id"]);

                    #region Add Hypercubes
                    List<HyperCubeBO> hypercubes = new List<HyperCubeBO>();
                    m_dtDefArc.DefaultView.RowFilter = "type='arc' and contextElement <> '' and definitionLink_id=" + defLink_Id;

                    foreach (DataRowView drv in m_dtDefArc.DefaultView)
                    {
                        try
                        {
                            if (drv["use"].ToString() == "prohibit")
                                continue;
                        }
                        catch { }

                        HyperCubeBO temp = new HyperCubeBO();
                        temp.HypercubeDefinedOn = drv["from"].ToString();
                        temp.Hypercube_Label = drv["to"].ToString();
                        m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + defLink_Id + " and label='" + temp.Hypercube_Label + "'";

                        temp.Hypercube_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //temp.Hypercube_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                        try { temp.Hypercube_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }

                        temp.ContextElement = (ContextElement)Enum.Parse(typeof(ContextElement), drv["contextElement"].ToString());
                        temp.ArcRole = (ArcRole)EnumExtensions.GetEnumValue(drv["arcRole"].ToString(), typeof(ArcRole));

                        //get all dimensions in the hypercube, hypercube can be defined in some other extended link also..

                        //look for hypercube in the same extended link prefer it.
                        m_dtDefArc.DefaultView.RowFilter = "from='" + temp.Hypercube_Label + "' and "
                            + "arcrole='http://xbrl.org/int/dim/arcrole/hypercube-dimension' and definitionLink_id="+defLink_Id;

                        //look for hypercube in all other extended links
                        //if we get multiple hypercubes in different extended links, what to do?
                        //currently all dim-dom in the diff hyc are added

                        if (m_dtDefArc.DefaultView.Count == 0)
                        {
                            m_dtDefArc.DefaultView.RowFilter = "from='" + temp.Hypercube_Label + "' and "
                            + "arcrole='http://xbrl.org/int/dim/arcrole/hypercube-dimension'";
                        }
                        //if hypercube is in some other def link, 
                        //get prim els from org def link and dim-dom from new def link.

                        //get all domains for all dimension in the hypercube
                        List<HycDimension> dimensions = new List<HycDimension>();
                        foreach (DataRowView drvDims in m_dtDefArc.DefaultView)
                        {
                            try
                            {
                                if (drvDims["use"].ToString() == "prohibit")
                                    continue;
                            }
                            catch { }

                            int hycDefLink = Convert.ToInt32(drvDims["definitionLink_id"]);

                            HycDimension hycDim = new HycDimension();
                            hycDim.Dimension_Label = drvDims["to"].ToString();
                            m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + hycDefLink + " and label='" + hycDim.Dimension_Label + "'";

                            hycDim.Dimension_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString()); 
                            //original
                            //hycDim.Dimension_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                            try { hycDim.Dimension_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                            catch { }
                            hycDim.ArcRole = ArcRole.Hypercube_Dimension;

                            m_dtDefArc.DefaultView.RowFilter = "from='" + hycDim.Dimension_Label + "' and "
                                + "arcrole='http://xbrl.org/int/dim/arcrole/dimension-domain' and definitionLink_id=" + hycDefLink;

                            foreach (DataRowView drvDoms in dsDefLin.Tables["definitionArc"].DefaultView)
                            {
                                try
                                {
                                    if (drvDoms["use"].ToString() == "prohibit")
                                        continue;
                                }
                                catch { }

                                HycDomain dom = new HycDomain();
                                dom.ArcRole = ArcRole.Dimension_Domain;
                                dom.Domain_Label = drvDoms["to"].ToString();
                                m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + hycDefLink + " and label='" + dom.Domain_Label + "'";

                                dom.Domain_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                                //original
                                //dom.Domain_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                                try { dom.Domain_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                                catch { }

                                if (hycDim.Domains == null)
                                    hycDim.Domains = new List<HycDomain>();
                                hycDim.Domains.Add(dom);

                                //adding all the parent and leaf domain-members
                                GetHycDomains(hycDefLink, dom);
                            }
                            dimensions.Add(hycDim);
                        }
                        temp.Dimensions = dimensions;

                        m_dtDefArc.DefaultView.RowFilter = "";

                        temp.HycPrimElement = new HycElement();
                        //temp.HycPrimElement.Id = new Loc();
                        temp.HycPrimElement.Id_Label = temp.HypercubeDefinedOn;
                        m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + defLink_Id + " and label='" 
                            + temp.HycPrimElement.Id_Label + "'";

                        temp.HycPrimElement.Id_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //temp.HycPrimElement.Id_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                        try { temp.HycPrimElement.Id_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }

                        GetHycElements(temp.HycPrimElement, defLink_Id);

                        hypercubes.Add(temp);
                    }
                    #endregion
                    defExtLink.HyperCubes = hypercubes;

                    m_dtDefArc.DefaultView.RowFilter = "arcrole='http://xbrl.org/int/dim/arcrole/dimension-default' and definitionLink_id=" + defLink_Id;
                    foreach (DataRowView drv in m_dtDefArc.DefaultView)
                    {
                        try
                        {
                            if (drv["use"].ToString() == "prohibit")
                                continue;
                        }
                        catch { }

                        if(defExtLink.DefaultDimensions ==null)
                            defExtLink.DefaultDimensions = new List<HycDimension>();

                        HycDimension hycDim = new HycDimension();
                        //hycDim.Dimension = new Loc();
                        hycDim.Dimension_Label = drv["from"].ToString();
                        m_dtLoc.DefaultView.RowFilter = "definitionLink_id="+defLink_Id+" and label='"+hycDim.Dimension_Label+"'";

                        hycDim.Dimension_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //hycDim.Dimension_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                        try { hycDim.Dimension_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }

                        //hycDim.Domain = new Loc();
                        HycDomain hycDom = new HycDomain();
                        hycDom.Domain_Label = drv["to"].ToString();
                        m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + defLink_Id + " and label='" + hycDom.Domain_Label + "'";

                        hycDom.Domain_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //hycDom.Domain_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                        try { hycDom.Domain_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }

                        hycDim.Domains = new List<HycDomain>();
                        hycDim.Domains.Add(hycDom);

                        defExtLink.DefaultDimensions.Add(hycDim);
                    }

                    //getting domains without members is necessary ??

                    defBO.DefintionLinks.Add(defExtLink);
                }
            }
            catch
            {

            }

            return defBO;
        }

        private void GetHycElements(HycElement primEl, int defLink_id)
        {
            //get all child primary elements for which this hypercube is defined
            m_dtDefArc.DefaultView.RowFilter = "from='" + primEl.Id_Label + "' and "
                        + " arcrole='http://xbrl.org/int/dim/arcrole/domain-member' and definitionLink_id=" + defLink_id;
            foreach (DataRowView drvEl in m_dtDefArc.DefaultView)
            {
                try
                {
                    if (drvEl["use"].ToString() == "prohibit")
                        continue;
                }
                catch { }

                if (primEl.Children == null)
                    primEl.Children = new List<HycElement>();

                HycElement temp = new HycElement();
                //temp.Id = new Loc();
                temp.Id_Label = drvEl["to"].ToString();
                m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + defLink_id + " and label='" + temp.Id_Label + "'";

                temp.Id_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                //original
                //temp.Id_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                try { temp.Id_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                catch { }

                try { temp.Use = drvEl["use"].ToString(); }
                catch { }
                temp.Order = Convert.ToDouble(drvEl["order"]);

                primEl.Children.Add(temp);

                GetHycElements(temp, defLink_id);
            }
        }

        //recursive function to get all the domain-members for a dimension
        private void GetHycDomains(int defHycLink, HycDomain hycDomain)
        {
            m_dtDefArc.DefaultView.RowFilter = "from='" + hycDomain.Domain_Label + "' and definitionLink_id="+defHycLink + " and "
                    + " arcrole='http://xbrl.org/int/dim/arcrole/domain-member'";

            foreach (DataRowView drv in m_dtDefArc.DefaultView)
            {
                try
                {
                    if (drv["use"].ToString() == "prohibit")
                        continue;
                }
                catch { }

                HycDomain hycDom = new HycDomain();
                
                hycDom.Domain_Label = drv["to"].ToString();
                m_dtLoc.DefaultView.RowFilter = "definitionLink_id=" + defHycLink + " and label='" + hycDom.Domain_Label + "'";

                hycDom.Domain_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                //original
                //hycDom.Domain_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                try { hycDom.Domain_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                catch { }
                hycDom.ArcRole = ArcRole.Domain_Member;

                if (hycDomain.ChildDomains == null)
                    hycDomain.ChildDomains = new List<HycDomain>();

                hycDomain.ChildDomains.Add(hycDom);

                GetHycDomains(defHycLink,hycDom);
            }
        }

        #endregion

        #region Calculation

        public CalculationLinkbaseBO ReadCalculationLinkbase(string calcLinPath)
        {
            CalculationLinkbaseBO calBO = new CalculationLinkbaseBO();
            try
            {
                string[] spl = calcLinPath.Split('\\');
                calBO.Href = spl[spl.Length - 1];

                calBO.CalculationLinks = new List<CalculationLinkBO>();
                DataSet dsCal = new DataSet();
                dsCal.ReadXml(calcLinPath);
                m_dtLoc = dsCal.Tables["loc"];
                m_dtCalArc = dsCal.Tables["calculationArc"];

                foreach (DataRow drCl in dsCal.Tables["calculationLink"].Rows)
                {
                    int calLink_id = Convert.ToInt32(drCl["calculationLink_id"]);

                    CalculationLinkBO calLinkBO = new CalculationLinkBO();
                    calLinkBO.ExtendedLinkRole = drCl["role"].ToString();
                    calLinkBO.Href = dsCal.Tables["roleRef"].Select("roleURI='"
                        + calLinkBO.ExtendedLinkRole + "'")[0]["href"].ToString();

                    m_dtCalArc.DefaultView.RowFilter = "calculationLink_id=" + calLink_id;

                    List<string> toEls = new List<string>();
                    foreach (DataRowView drv in m_dtCalArc.DefaultView)
                    {
                        toEls.Add(drv["to"].ToString());
                    }
                    List<string> rootEls = new List<string>();

                    DataView dvRoots = new DataView(m_dtCalArc, "from not in ('"
                        + string.Join("','", toEls.Distinct().ToArray<string>()) + "') and calculationLink_id=" + calLink_id, null, DataViewRowState.CurrentRows);

                    foreach (DataRowView drv in dvRoots)
                    {
                        rootEls.Add(drv["from"].ToString());
                    }

                    calLinkBO.Calculations = new List<CalculationBO>();
                    foreach (string rootEl in rootEls.Distinct())
                    {
                        CalculationBO calRoot = new CalculationBO();

                        //Loc loc = new Loc();
                        calRoot.Element_Label = rootEl;
                        m_dtLoc.DefaultView.RowFilter = "calculationLink_id=" + calLink_id + " and label='" + calRoot.Element_Label + "'";

                        calRoot.Element_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //calRoot.Element_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                        try { calRoot.Element_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }
                        //calRoot.Element = loc;
                        CreateCalculationArc(calRoot, calLink_id);

                        calLinkBO.Calculations.Add(calRoot);
                    }

                    calBO.CalculationLinks.Add(calLinkBO);
                }
            }
            catch
            {

            }

            return calBO;
            //handle summation-item, item-summation types..
        }

        void CreateCalculationArc(CalculationBO cal, int calLink_id)
        {

            DataView dvChildren = new DataView(m_dtCalArc, "from='" + cal.Element_Label + "' and calculationLink_id="
                        + calLink_id + " and arcrole='http://www.xbrl.org/2003/arcrole/summation-item'", null, DataViewRowState.CurrentRows);

            foreach (DataRowView drvChild in dvChildren)
            {
                try
                {
                    if (drvChild["use"].ToString() == "prohibit")
                        continue;
                }
                catch { }

                CalculationBO calChild = new CalculationBO();
                //Loc loc1 = new Loc();
                calChild.Element_Label = drvChild["to"].ToString();
                m_dtLoc.DefaultView.RowFilter = "calculationLink_id=" + calLink_id + " and label='" + calChild.Element_Label + "'";

                calChild.Element_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                //original
                //calChild.Element_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                try { calChild.Element_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                catch { }
                //calChild.Element = loc1;

                calChild.Weight = Convert.ToDouble(drvChild["weight"]);
                calChild.Order = Convert.ToDouble(drvChild["order"]);
                try { calChild.Title = drvChild["title"].ToString(); }
                catch { }

                if (cal.Children == null)
                    cal.Children = new List<CalculationBO>();

                //add in order
                bool added = false;
                for (int a = 0; a < cal.Children.Count; a++)
                {
                    if (calChild.Order < cal.Children[a].Order)
                    {
                        cal.Children.Insert(a, calChild);
                        added = true;
                        break;
                    }
                }

                if (!added)
                    cal.Children.Add(calChild);

                CreateCalculationArc(calChild, calLink_id);
            }
        }

        #endregion

        #region Presentation

        public PresentationLinkbaseBO ReadPresentationLinkbase(string presLinPath)
        {
            PresentationLinkbaseBO presBO = new PresentationLinkbaseBO();

            try
            {

                string[] spl = presLinPath.Split('\\');
                presBO.Href = spl[spl.Length - 1];

                presBO.PresentationLinks = new List<PresentationLinkBO>();
                DataSet dsPres = new DataSet();
                dsPres.ReadXml(presLinPath);
                m_dtLoc = dsPres.Tables["loc"];
                m_dtPresArc = dsPres.Tables["presentationArc"];

                foreach (DataRow drPr in dsPres.Tables["presentationLink"].Rows)
                {
                    int presLink_id = Convert.ToInt32(drPr["presentationLink_id"]);

                    PresentationLinkBO presLinkBO = new PresentationLinkBO();
                    presLinkBO.ExtendedLinkRole = drPr["role"].ToString();
                    presLinkBO.Href = dsPres.Tables["roleRef"].Select("roleURI='"
                        + presLinkBO.ExtendedLinkRole + "'")[0]["href"].ToString();

                    m_dtPresArc.DefaultView.RowFilter = "presentationLink_id=" + presLink_id;

                    List<string> toEls = new List<string>();
                    foreach (DataRowView drv in m_dtPresArc.DefaultView)
                    {
                        toEls.Add(drv["to"].ToString());
                    }
                    List<string> rootEls = new List<string>();

                    DataView dvRoots = new DataView(m_dtPresArc, "from not in ('"
                        + string.Join("','", toEls.Distinct().ToArray<string>()) + "') and presentationLink_id=" + presLink_id, null, DataViewRowState.CurrentRows);

                    foreach (DataRowView drv in dvRoots)
                    {
                        rootEls.Add(drv["from"].ToString());
                    }

                    presLinkBO.Presentations = new List<PresentationBO>();
                    foreach (string rootEl in rootEls.Distinct())
                    {
                        PresentationBO presRoot = new PresentationBO();

                        //Loc loc = new Loc();
                        presRoot.Element_Label = rootEl;
                        m_dtLoc.DefaultView.RowFilter = "presentationLink_id=" + presLink_id + " and label='" + presRoot.Element_Label + "'";

                        presRoot.Element_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                        //original
                        //presRoot.Element_Href = m_dtLoc.DefaultView[0]["href"].ToString();
                        try { presRoot.Element_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                        catch { }
                        //presRoot.Element = loc;
                        presRoot.PreferredLabelRole = LabelRole.label.ToDescriptionString();
                        CreatePresentationArc(presRoot, presLink_id);

                        presLinkBO.Presentations.Add(presRoot);
                    }

                    presBO.PresentationLinks.Add(presLinkBO);
                }
            }
            catch
            {

            }

            return presBO;

            //handle parent-child, child-parent types
        }

        void CreatePresentationArc(PresentationBO pres, int presLink_id)
        {
            DataView dvChildren = new DataView(m_dtPresArc, "from='" + pres.Element_Label + "' and presentationLink_id="
                        + presLink_id + " and arcrole='http://www.xbrl.org/2003/arcrole/parent-child'", null, DataViewRowState.CurrentRows);

            foreach (DataRowView drvChild in dvChildren)
            {
                try
                {
                    if (drvChild["use"].ToString() == "prohibit")
                        continue;
                }
                catch { }

                PresentationBO presChild = new PresentationBO();
                //Loc loc1 = new Loc();
                presChild.Element_Label = drvChild["to"].ToString();
                m_dtLoc.DefaultView.RowFilter = "presentationLink_id=" + presLink_id + " and label='" + presChild.Element_Label + "'";

                presChild.Element_Href = GetHref(m_dtLoc.DefaultView[0]["href"].ToString());
                //original
                //presChild.Element_Href = m_dtLoc.DefaultView[0]["href"].ToString();

                try { presChild.Element_Title = m_dtLoc.DefaultView[0]["title"].ToString(); }
                catch { }
                //presChild.Element = loc1;

                presChild.Order = Convert.ToDouble(drvChild["order"]);
                try { presChild.Show = drvChild["weight"].ToString(); }
                catch { }
                try { presChild.Title = drvChild["title"].ToString(); }
                catch { }
                //try { presChild.PreferredLabelRole = (LabelRole)EnumExtensions.GetEnumValue(drvChild["preferredLabel"].ToString(), typeof(LabelRole)); }
                //catch { presChild.PreferredLabelRole = LabelRole.label; }

                try{ presChild.PreferredLabelRole = drvChild["preferredLabel"].ToString(); }
                catch { presChild.PreferredLabelRole = ""; }

                if (presChild.PreferredLabelRole == "")
                {
                    presChild.PreferredLabelRole = LabelRole.label.ToDescriptionString();
                }

                if (pres.Children == null)
                    pres.Children = new List<PresentationBO>();

                //add in order
                bool added = false;
                for (int a = 0; a < pres.Children.Count; a++)
                {
                    if (presChild.Order < pres.Children[a].Order)
                    {
                        pres.Children.Insert(a, presChild);
                        added = true;
                        break;
                    }
                }

                if(!added)
                    pres.Children.Add(presChild);

                CreatePresentationArc(presChild, presLink_id);
            }
        }

        #endregion

        /// <summary>
        /// remove http and ../ from element_href xsd part of linkbase elements
        /// </summary>
        /// <param name="href"></param>
        /// <returns></returns>
        private string GetHref(string href)
        {
            //need to remove http and ../ from element_href for presenatation-elements to get their labels correctly
            string[] spl1 = href.Split('#');
            if (spl1[0].Contains('/'))
            {
                string[] spl2 = spl1[0].Split('/');
                spl1[0] = spl2[spl2.Length - 1];
            }
            return spl1[0] + "#" + spl1[1];
        }
    }
}
